home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Software Vault: The Gold Collection
/
Software Vault - The Gold Collection (American Databankers) (1993).ISO
/
cdr49
/
118_01.zip
/
SYMTAB.BDS
< prev
next >
Wrap
Text File
|
1993-06-03
|
9KB
|
445 lines
/* Symbol table routines for Software Tools
* source: symtab.bds
* version: November 27, 1981
*/
#include tools.h
/* These routines assume that the data field in each node
* has the following format:
*
* name field: string, ends with EOS.
* value field: string, ends with EOS.
*
* The length of these fields is arbritrary;
* that is why they are not made part of struct node.
* The table lookup routines examine only the name field.
* This format works well for macros, but may not be so
* good for numeric fields which may contain embedded EOS
* characters.
*/
/* format of each symbol table */
struct symtab {
char stchk; /* check byte */
int htsize; /* size of hash table */
struct node *hashtab [1]; /* start of hash table */
};
#define TABCHK "T" /* only legal value for stchk */
#define STHEAD 3 /* size of fixed part of symtab */
/* format of each node */
struct node {
char nchk; /* check byte */
struct node *next; /* pointer to next node */
char data [1]; /* first byte of data field */
};
#define NODE "N" /* only legal value for nchk */
#define NHEAD 3 /* size of fixed part of node */
/* These routines have different calling sequences from
* the RATFOR routines from the Software Tools Users Group:
*
*
* RATFOR: delete (symbol, table)
* char *symbol, *table;
*
* C: delete (symbol, table)
* char *symbol;
* struct symtab *table;
*
*
* RATFOR: enter (symbol, info, table)
* char *symbol;
* int info;
* char *table;
*
* C: enter (symbol, info, table)
* char *symbol, *info;
* struct symtab *table;
*
*
* RATFOR: lookup (symbol, info, table)
* char *symbol, *info, *table;
* (copy information to info []);
*
* C: lookup (symbol, table)
* char *symbol;
* struct symtab *table;
* (return pointer to info field)
*
*
* RATFOR: mktabl (nodesize)
* int nodesize;
*
* C: mktable (htsize)
* int htsize;
*
*
* RATFOR: rmtabl (table)
* char *table;
*
* C: rmtabl (table)
* struct symtab *table;
*
*
* RATFOR: sctabl (table, sym, info, posn)
* char *table, *sym, *info;
* int *posn;
* (copy fields to sym [] and info [])
*
* C: sctabl (table, posn)
* struct symtab *table;
* int *posn;
* (return pointer to data field of node)
*
*/
#define NTABS 10 /* number of symbol tables */
main(argc, argv)
int argc;
char **argv;
{
initst(argc, argv);
main1();
endst();
}
main1()
{
char inbuf[100]; /* input buffer */
int i, number;
char *tables [NTABS]; /* pointer to symbol tables */
char symbol [100]; /* symbol name */
char info [100]; /* info field of symbol */
/* init available memory */
dsinit();
printf("\nTest of symtab.bds: August 27, 1981\n");
for (i = 0; i < NTABS; i++) {
tables [i] = 0;
}
/* main loop */
for(;;) {
printf("\nEnter table number or ");
printf("-1 to exit or ");
printf("-2 to dump tables.\n");
_gets(inbuf);
number = atoi(inbuf);
if (number == -1) {
return;
}
if (number == -2) {
for (i = 0; i < NTABS; i++) {
if (tables [i] != 0) {
printf("\nDump of table %d\n",i);
dumptabl (tables [i]);
}
}
continue;
}
if (number < 0 || number >= NTABS) {
printf("Bad table number\n");
continue;
}
/* create table if needed */
if (tables [number] == 0) {
printf("Creating table %d\n",number);
tables [number] = mktabl(33);
printf("Table %d at %x\n",
number, tables [number]);
}
/* get name of symbol */
printf("Enter symbol name\n");
_gets(symbol);
if (symbol [0] == 0) {
continue;
}
/* delete if info field is null */
printf("Enter info field or CR\n");
_gets(info);
if (info [0] == 0) {
delete(symbol, tables [number]);
}
else {
enter(symbol, info, tables [number]);
}
}
}
/* delete - remove a symbol from the symbol table */
delete (symbol, table)
char *symbol;
struct symtab *table;
{
int h;
struct node *n, *n1;
/* comment out -----
printf("In delete: symbol = %s, table = %x\n",
symbol, table);
----- end comment out */
/* point at list of buckets */
h = hashfunc(symbol, table -> htsize);
n = table -> hashtab [h];
/* the first bucket is a special case so that the code
* is independent of the format of struct symtab.
*/
if (n == 0) {
return;
}
if (equal(symbol, n -> data)) {
table -> hashtab [h] = n -> next;
dsfree(n);
return;
}
/* general case: search list of buckets */
n1 = n; /* n1 points at previous bucket */
n = n -> next; /* n points at current bucket */
while (n) {
if (equal(symbol, n -> data)) {
n1 -> next = n -> next;
dsfree(n);
return;
}
else {
n1 = n;
n = n -> next;
}
}
}
/* dumptabl -- dump all symbols of a symbol table */
dumptabl (table)
struct symtab *table;
{
int i, k, posn;
char *n, *symbol, *info;
int *p;
/* dump hash table */
printf("The hash table is:\n\n");
for (i = 0; i < table -> htsize; i++) {
if (k = table -> hashtab [i]) {
printf("hashtab [%3d] = %x\n",
i, k);
}
}
/* print all the nodes in the table */
posn = 0;
while (symbol = sctabl(table, &posn)) {
info = symbol;
while (*info++ != EOS) {
;
}
p = symbol - 2;
printf("node = %x, ", symbol);
printf("next = %x, ", *p);
printf("symbol = %s, ", symbol);
printf("info = %s\n", info);
}
}
/* enter -- place a symbol in the symbol table
* update entry if already present
*/
enter (symbol, info, table)
char *symbol, *info;
struct symtab *table;
{
struct node *n;
int i, h, k;
/* allocate another node */
k = (length(symbol) + 1) + (length(info) + 1) + NHEAD;
/* use a cast for maximum portability:
* n = (struct * node) dsget (k);
*/
n = dsget (k);
/* set header fields of node */
n -> nchk = NODE;
/* copy symbol and info to data area */
i = 0;
stcopy (symbol, 0, n -> data, &i);
i++;
scopy (info, 0, n -> data, i);
/* hang node from hash table */
h = hashfunc(symbol, table -> htsize);
n -> next = table -> hashtab [h];
table -> hashtab [h] = n;
}
/* compute the hash function for symbol in a table with
* n entries.
*/
hashfunc (symbol, n)
char *symbol;
int n;
{
int i, h;
h = 0;
for (i = 0; symbol[i] != EOS; i++) {
h += symbol [i];
}
return (h%n);
}
/* lookup - return pointer to info for symbol in table.
* -- return 0 if symbol not in table
*/
char *lookup (symbol, table)
char *symbol;
struct symtab * table;
{
int h;
struct node *n;
char *p;
h = hashfunc(symbol, table -> htsize);
n = table -> hashtab [h];
for ( ; n; n = n -> next) {
if (equal(symbol, n -> data)) {
/* point p at info field */
p = n -> data;
while (*p++ != EOS) {
;
}
return(p);
}
}
return (0);
}
/* mktabl - make a new (empty) symbol table */
char *mktabl (hashsize)
int hashsize;
{
char *dsget();
struct symtab *table;
int i;
/* get storage for the table.
* use a cast for maximum portability:
* table = (symtab *) dsget (...);
*/
table = dsget ((2 * hashsize) + STHEAD);
/* fill in the debugging byte */
table -> stchk = TABCHK;
/* fill in the size of the table */
table -> htsize = hashsize;
/* zero out the hash table */
for (i = 0; i < hashsize; i++) {
table -> hashtab [i] = 0;
}
return(table);
}
/* rmtabl - remove a symbol table, deleting all entries */
rmtabl (table)
struct symtab *table;
{
struct node *n, *n1;
int i;
/* check debugging byte */
if (table -> stchk != TABCHK) {
syserr ("rmtabl: bad check byte");
}
/* free every entry in hash table */
for (i = 0; i < table -> htsize; i++) {
n = table -> hashtab [i];
while (n) {
n1 = n -> next;
dsfree(n);
n = n1;
}
}
/* free the symbol table itself.
* a cast would be best: dsfree( (char *) table);
*/
dsfree(table);
printf("End of rmtabl\n");
}
/* sctabl -- scan symbol table.
* update *posn.
* return pointer to data field or 0.
*/
char *sctabl (table, posn)
struct symtab *table;
int *posn;
{
int i, count;
struct node *n;
count = 0;
for (i = 0; i < table -> htsize; i++) {
n = table -> hashtab [i];
while (n) {
if (count == *posn) {
(*posn)++;
return (n -> data);
}
else {
count++;
n = n -> next;
}
}
}
(*posn)++;
return(0);
}
/* sctabl -- scan symbol table.
* update *posn.
* return pointer to data field or 0.
*/
char *sctabl (table, posn)
struct symtab *table;
int *posn;
{
int i, count;
struct node *n;
count = 0;
for (i = 0; i <